using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Services;
using MainGame;
using MainGame.Menu;
using MainGame.GameSound;

namespace MainGame.GamePlay
{
  using XNAColor = Microsoft.Xna.Framework.Color;
  using System.Text;

  public delegate void OnMenuPause();
  public delegate void OnHelpScreen();
  public delegate void OnDecoration();
  public delegate void OnMatchExit();

  /// <summary>
  /// Servizio di UI: lancia eventi per il click sui bottoni gestiti
  /// </summary>
  public interface IUIRenderer
  {
    float elapsedTime { get; set; }

    event OnMenuPause OnMenuPause;
    event OnHelpScreen OnHelpScreen;
    event OnDecoration OnDecoration;
  }

  /// <summary>
  /// Disegna la UI del gioco e gestisce il click sul bottone Next Turn
  /// </summary>
  public class UIRenderer : MainGame.Menu.BaseMenu, IUIRenderer
  {
    public float elapsedTime { get; set; }
    public UIRenderer(Game game, MenuDepths depth)
      : base(game, depth)
    {
      UpdateOrder = (int)ComponentOrders.UI;
      bounds = game.GraphicsDevice.Viewport.Bounds;

      game.Services.AddService(typeof(IUIRenderer), this);
    }

    protected override void Dispose(bool disposing)
    {
      Game.Services.RemoveService(typeof(IUIRenderer));
      base.Dispose(disposing);
    }

    IBoardState board;
    Texture2D clock, glass, barr, box, noteOn, noteOff;
    Vector2 clockPosition, clockEndPosition;
    Button HelpButton, MenuButton, MusicButton, NextSongButton;
    private bool musicON = true;
    //private Rectangle songRectangle;
    ISoundManager<GamePlaySounds> soundManager;
    public BoardRenderer.RenderState renderState;
    public bool Outro;

    public override void Initialize()
    {      
      board = Game.GetBoardManager();

      if (OnDecoration != null)
        OnDecoration();

      soundManager = Game.Services.GetService(typeof(ISoundManager<GamePlaySounds>)) as ISoundManager<GamePlaySounds>;

      clock = Game.Content.Load<Texture2D>(@"Images//Game//Clock");
      glass = Game.Content.Load<Texture2D>(@"Images//Game//ClockGlass");
      barr = Game.Content.Load<Texture2D>(@"Images//Game//barr");
      box = Game.Content.Load<Texture2D>(@"Images//Game//roundedBox");

      noteOn = Game.Content.Load<Texture2D>(@"Images//Menu//note");
      noteOff = Game.Content.Load<Texture2D>(@"Images//Menu//noteOFF");

      // Bottoni
      HelpButton = new Button(Game, @"Images//Menu//HelpButton", new Rectangle(10, -55, 80, 40), XNAColor.White, "baveuse1_font", "", XNAColor.Gold, 0.8f);
      MenuButton = new Button(Game, @"Images//Menu//PauseButton", new Rectangle(715, -55, 80, 40), XNAColor.White, "small_font", "", XNAColor.Yellow);

      AddButton(HelpButton, () => {
        if (renderState != BoardRenderer.RenderState.Intro)
        {
          HelpButton.touched = true;
          HelpButton.color = XNAColor.Red;
          if (OnHelpScreen != null)
            OnHelpScreen();
        }
      });

      AddButton(MenuButton, () => {
        if (renderState != BoardRenderer.RenderState.Intro)
        {
          MenuButton.touched = true;
          MenuButton.color = XNAColor.Red;
          if (OnMenuPause != null)
            OnMenuPause();
        }
      });
  
      // Music controls
      //var viewport = Game.GraphicsDevice.Viewport;
      //songRectangle = new Rectangle(viewport.Width / 2, viewport.Height - 50, 200, 30);
      //infoBox = Game.Content.Load<Texture2D>(@"Images//Game//roundedBox");
      MusicButton = new Button(Game, @"Images//Menu//note", new Rectangle(750, 492, 40, 40), "small_font", "");
      AddButton(MusicButton, () =>
      {
        musicON = (!musicON);
        if (musicON)
        {
          MusicButton.texture = noteOn;
          //soundManager.MusicMuted = false;
          //soundManager.PlayNextSong();
          soundManager.SfxMuted = false;
          Game.GetContext().currentConfig.sfxMuted = false;
        }
        if (!musicON)
        {
          MusicButton.texture = noteOff;
          //soundManager.MusicMuted = true;
          //soundManager.StopMusic();
          soundManager.SfxMuted = true;
          Game.GetContext().currentConfig.sfxMuted = true;
        }
      });

      //NextSongButton = new Button(Game, @"Images//Game//FwdArrows", new Rectangle(songRectangle.X + songRectangle.Width + 5, songRectangle.Y, 30, 30), "small_font", "");
      //AddButton(NextSongButton, () =>
      //{
      //  soundManager.PlayNextSong();
      //});

      clockPosition = new Vector2(350, 10);
      clockEndPosition = new Vector2(560, 280);

      // Load audio settings from context
      musicON = !Game.GetContext().currentConfig.sfxMuted;
      if (musicON)
        MusicButton.texture = noteOn;
      if (!musicON)
        MusicButton.texture = noteOff;

      var boardRenderer = Game.Services.GetService(typeof(IBoardRenderer)) as BoardRenderer;
      renderState = boardRenderer.renderState;
      if (renderState != BoardRenderer.RenderState.Intro)
      {
        intro = 60;
        HelpButton.bounds.Offset(0, intro);
        MenuButton.bounds.Offset(0, intro);
        MusicButton.bounds.Offset(0, -intro);
      }
      Outro = false;

      base.Initialize();
    }

    Matrix screen_transform;
    SpriteBatch sprite_batch;
    SpriteFont large_font, small_font;
    XNAColor textColor = XNAColor.Black;  
    Texture2D white_pixel;
    protected override void LoadContent()
    {
      sprite_batch = Game.GetContext().SpriteBatch;
      screen_transform = Game.GetContext().ScreenTransform;
      large_font = Game.Content.Load<SpriteFont>("large_font");
      small_font = Game.Content.Load<SpriteFont>("small_font");
      white_pixel = Game.Content.Load<Texture2D>("white_pixel");

      base.LoadContent();
    }

    int intro = 0;
    //string songName = "";
    public override void Update(GameTime gameTime)
    {
      var boardRenderer = Game.Services.GetService(typeof(IBoardRenderer)) as BoardRenderer;
      if (boardRenderer != null)
        renderState = boardRenderer.renderState;

      if (!Outro)
      {
        elapsedTime += gameTime.dt();

        if (renderState != BoardRenderer.RenderState.Intro)
        {
          // Input: back button pressed
          if (((Game1)Game).IsBackButtonPressed())
          {
            MenuButton.color = XNAColor.Red;
            if (OnMenuPause != null)
              OnMenuPause();
          }

          // Ripristina colore Bottoni
          //HelpButton.color = XNAColor.Blue;
          //MenuButton.color = XNAColor.Blue;

          // Anima titolo traccia audio
          //songName = soundManager.GetSongName();
          //if (songName.Length > 0)
          //  songName = songName.Insert(songName.Length, "  ***  ");
          //if (small_font.MeasureString(songName).X > songRectangle.Width)
          //{
          //  int songNameStartChr = (int)(elapsedTime / 0.5f) % songName.Length;
          //  int rectLenInChars = (int)(songName.Length * (songRectangle.Width - 10) / small_font.MeasureString(songName).X) - 1;
          //  int songNameLastChr = songNameStartChr + rectLenInChars;
          //  if (songNameLastChr - (songName.Length - 1) >= 0)
          //    songName = songName.Insert(songName.Length, songName.Substring(0, songNameLastChr - (songName.Length - 1)));
          //  songName = songName.Substring(songNameStartChr, rectLenInChars);
          //}
        }
      }

      if (renderState == BoardRenderer.RenderState.Intro)
      {
        // Input: back button pressed
        if (((Game1)Game).IsBackButtonPressed())
        {
          MenuButton.color = XNAColor.Red;
          if (OnMatchExit != null)
            OnMatchExit();
        }

        if (intro < 60) intro++;
        if (HelpButton.bounds.Y < 5) HelpButton.bounds.Offset(0, 1);
        if (MenuButton.bounds.Y < 5) MenuButton.bounds.Offset(0, 1);
        if (MusicButton.bounds.Y > 432) MusicButton.bounds.Offset(0, -1);
      }

      if (Outro)     
      {
        buttons.Clear();

        //Vector2 toDestination = clockEndPosition - clockPosition;
        //if (toDestination.Length() > 10)
        //{
        //  toDestination.Normalize();
        //  toDestination *= 10;
        //  clockPosition += toDestination;
        //}
        //else
        //{
        //  clockPosition = clockEndPosition;
        //  textColor = XNAColor.Green;
        //}
      }
      
      base.Update(gameTime);
    }


    public override void Draw(GameTime gameTime)
    {
      sprite_batch.Begin();

      if (!Outro)
      {
        // Barra Interfaccia (Entrata Slide)
        sprite_batch.Draw(barr, new Rectangle(0, -60 + intro, 800, 60), new XNAColor(200, 200, 200, 200));

        // Oscura la Schermata di Gioco
        if (this.Enabled == false) sprite_batch.Draw(white_pixel, Game.GraphicsDevice.Viewport.Bounds, new XNAColor(0, 0, 0, 100));

        // Disegna il Nome del Giocatore
        if (!board.Players.ElementAt(0).Name.Equals("default"))
        {
          sprite_batch.DrawString(small_font, board.Players.ElementAt(0).Name, new Vector2(550, -53 + intro), XNAColor.Gray);
          sprite_batch.DrawString(small_font, board.Players.ElementAt(0).Name, new Vector2(551, -52 + intro), textColor);
        }
        else
        {
          sprite_batch.DrawString(small_font, Locale.Strings.CreateProfHint.Replace("\\n", "\n"), new Vector2(550, -53 + intro), XNAColor.Gray, 0.0f, Vector2.Zero, 0.7f, SpriteEffects.None, 0.0f);
          sprite_batch.DrawString(small_font, Locale.Strings.CreateProfHint.Replace("\\n", "\n"), new Vector2(551, -53 + intro), textColor, 0.0f, Vector2.Zero, 0.7f, SpriteEffects.None, 0.0f);
        }

        // Disegna fondino controllo audio
        sprite_batch.Draw(box, new Rectangle(740, 480 - intro, 80, intro + 10), null, new XNAColor(200, 200, 200, 200), 0.0f, Vector2.Zero, SpriteEffects.None, 0.99f);

        // Visualizza titolo traccia audio
        //sprite_batch.Draw(Game.Content.Load<Texture2D>("white_pixel"), new Rectangle(songRectangle.Left - 38, songRectangle.Top - 3, songRectangle.Width + 76, songRectangle.Height + 26), XNAColor.BlanchedAlmond);
        //sprite_batch.Draw(Game.Content.Load<Texture2D>("white_pixel"), songRectangle, XNAColor.Black);
        //sprite_batch.DrawString(small_font, songName, new Vector2(songRectangle.Left + 3, songRectangle.Top), XNAColor.Gold);
      }

      //Visualizza Time
      if (Enabled)
      {
        sprite_batch.Draw(clock, new Rectangle((int)clockPosition.X, (int)clockPosition.Y, 50, 50), XNAColor.White);
        sprite_batch.Draw(white_pixel, new Rectangle((int)clockPosition.X + 25, (int)clockPosition.Y + 25, 2, 20), null, XNAColor.Black, elapsedTime % (float)(2 * Math.PI), Vector2.Zero, SpriteEffects.None, 1.0f);
        sprite_batch.Draw(glass, new Rectangle((int)clockPosition.X, (int)clockPosition.Y, 50, 50), new XNAColor(100,100,100,100));

        TimeSpan elapsedTimeSpan = TimeSpan.FromSeconds((double)elapsedTime);
        string printedTime = elapsedTimeSpan.Minutes + ":" + elapsedTimeSpan.Seconds;
        if (elapsedTimeSpan.Minutes < 10)
          printedTime = printedTime.Insert(0, "0");
        if (elapsedTimeSpan.Seconds < 10)
          printedTime = printedTime.Insert(printedTime.Length - 1, "0");
        //string printedTime = String.Format("{0}:{1}", elapsedTimeSpan.Minutes, elapsedTimeSpan.Seconds);
        //string printedTime = String.Format("{0:mm}:{1:ss}", elapsedTimeSpan, elapsedTimeSpan);
        sprite_batch.DrawString(large_font, printedTime, clockPosition + new Vector2(50, -3), XNAColor.Gray);
        sprite_batch.DrawString(large_font, printedTime, clockPosition + new Vector2(51, -2), textColor);
      }
      else
      {
        sprite_batch.DrawString(large_font, Locale.Strings.Pause, new Vector2(350, 7), XNAColor.Gray);
        sprite_batch.DrawString(large_font, Locale.Strings.Pause, new Vector2(351, 8), textColor);
      }

      sprite_batch.End();

      base.Draw(gameTime);
    }

    public event OnMenuPause OnMenuPause;
    public event OnHelpScreen OnHelpScreen;
    public event OnDecoration OnDecoration;
    public event OnMatchExit OnMatchExit;
  }
}
